package online.heycm.platform.rocketmq.common.entity;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import online.heycm.platform.common.entity.constant.Constant;
import online.heycm.platform.common.tools.Jackson;
import online.heycm.platform.rocketmq.common.handler.LocalTransactionHandler;
import org.slf4j.MDC;

/**
 * 事件模型
 *
 * @author heycm
 * @since 2023/11/29 20:58
 */
@Getter
public class Event {

    /**
     * 事件ID/TraceId
     */
    private String eventId;

    /**
     * 事件主题，完整事件路由由 [主题.事件] 组合而成，如：online-heycm-rocketmq.test
     */
    private String eventTopic;

    /**
     * 事件名称，完整事件路由由 [主题.事件] 组合而成，如：online-heycm-rocketmq.test
     */
    private String eventName;

    /**
     * 事件上下文
     */
    private Context context;

    /**
     * 发送超时，默认3000ms
     */
    private long timeout = 3000L;

    /**
     * 延迟消息等级："1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h" 如：delay=1为延迟1s，delay=18为延迟2h
     */
    private int delay;

    /**
     * 顺序消息HashKey
     */
    private String hash;

    @JsonIgnore
    private LocalTransactionHandler localTransactionHandler;

    private Event() {
        this.eventId = MDC.get(Constant.TRACE_ID);
    }

    private Event(String event) {
        this.eventId = MDC.get(Constant.TRACE_ID);
        split(event);
    }

    public static Event of(String event) {
        return new Event(event);
    }

    public static Event of(String event, Context context) {
        Event e = new Event(event);
        e.context = context;
        return e;
    }

    public static Event of(String event, Context context, LocalTransactionHandler localTransactionHandler) {
        Event e = of(event, context);
        e.localTransactionHandler = localTransactionHandler;
        return e;
    }

    public static Event of(String event, String data) {
        Event e = new Event(event);
        e.context = Context.of(data);
        return e;
    }

    public static Event of(String event, String data, LocalTransactionHandler localTransactionHandler) {
        Event e = of(event, data);
        e.localTransactionHandler = localTransactionHandler;
        return e;
    }

    public Event eventId(String eventId) {
        this.eventId = eventId;
        return this;
    }

    public Event event(String event) {
        split(event);
        return this;
    }

    public Event context(Context context) {
        this.context = context;
        return this;
    }

    public Event timeout(long timeout) {
        this.timeout = timeout;
        return this;
    }

    public Event delay(int delay) {
        this.delay = delay;
        return this;
    }

    public Event hash(String hash) {
        this.hash = hash;
        return this;
    }

    @Override
    public String toString() {
        return toJson();
    }

    public String toJson() {
        return Jackson.toJson(this);
    }

    private void split(String event) {
        String[] split = event.split("\\.");
        this.eventTopic = split[0];
        this.eventName = split.length > 1 ? split[1] : null;
    }
}
